﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace TouchControls
{
    public class NetworkPanel : Panel
    {
        #region private variables
        double _Rayon;
        double _TotalHeight;
        double _ChildSpace;
        double _Offset;
        double _MaxWidth;
        #endregion private variables        

        #region DP Properties
        
        //public double Zoom
        //{
        //    get { return (double)GetValue(ZoomProperty); }
        //    set { SetValue(ZoomProperty, value); }
        //}


        public Canvas LineCanvas
        {
            get { return (Canvas)GetValue(LineCanvasProperty); }
            set { SetValue(LineCanvasProperty, value); }
        }


        public VisualState ExpandedState
        {
            get { return (VisualState)GetValue(ExpandedStateProperty); }
            set { SetValue(ExpandedStateProperty, value); }
        }

        public VisualState CollapsedState
        {
            get { return (VisualState)GetValue(CollapsedStateProperty); }
            set { SetValue(CollapsedStateProperty, value); }
        }

        public static readonly DependencyProperty LineCanvasProperty =
            DependencyProperty.Register("LineCanvas", typeof(Canvas), typeof(NetworkPanel), null);
        
        //public static readonly DependencyProperty ZoomProperty =
        //    DependencyProperty.Register("Zoom", typeof(double), typeof(NetworkPanel), new PropertyMetadata(new PropertyChangedCallback(ZoomChanged)));
        //public static void ZoomChanged(
        //            DependencyObject d,
        //            DependencyPropertyChangedEventArgs e
        //            )
        //{
        //    (d as NetworkPanel).InvalidateMeasure();
        //}


        public static readonly DependencyProperty ExpandedStateProperty =
            DependencyProperty.Register("ExpandedState", typeof(VisualState), typeof(NetworkPanel), null);


        public static readonly DependencyProperty CollapsedStateProperty =
            DependencyProperty.Register("CollapsedState", typeof(VisualState), typeof(NetworkPanel), null);

        
        #endregion DP Properties

        #region ctor
        public NetworkPanel()
        {
            _ChildSpace = 5;
            _Offset = 10;
            /*Zoom = 1;*/
           
        }
        #endregion ctor

        #region panel implementation
        private Line CreateNewLine(NetworkTree parent)
        {
            Line _result = new Line();
            _result.StrokeThickness = parent.LineThickness;
            _result.Stroke = parent.LineBrush;
            return _result;
        }

        private void CheckLines(NetworkTree parent)
        {
            if (LineCanvas != null)
            {
                int _nbLines = Children.Count;
                if (LineCanvas.Children.Count != _nbLines)
                {
                    LineCanvas.Children.Clear();
                    for (int i = 1; i <= _nbLines; i++)
                    {
                        LineCanvas.Children.Add(CreateNewLine(parent));
                    }
                }
            }
        }


        double _coef = 3.9; //3.5
            

        protected override Size ArrangeOverride(Size finalSize)
        {//V5

            double _totalHeight = _TotalHeight; // *Zoom;
            double _centerYDelta = (finalSize.Height - _totalHeight) / 2;
            double _hSum = 0;
            var parent = this.FindParent<NetworkTree>();
            if (!parent.IsExpanded) return finalSize;

            double maxWidth = 0;

            int _index = 0;
            foreach (FrameworkElement child in InternalChildren)
            {
                double _h = (_totalHeight / 2 - _hSum);
                double XFromCenter = Math.Sqrt(_Rayon * _Rayon - _h * _h);
                double X = XFromCenter - (_Rayon - _Rayon / _coef) + _Offset;
                double Y = _hSum /* Zoom*/ + _centerYDelta;
                
                if (LineCanvas != null)
                {
                    Line _line = LineCanvas.Children[_index] as Line;
                    _line.X1 = 0;
                    _line.Y1 = finalSize.Height / 2;
                    _line.X2 = X + parent.LineThickness;
                    _line.Y2 = Y + child.DesiredSize.Height / 2;
                }
                
                Rect _finalRect = new Rect(new Point(X, Y), child.DesiredSize);
                child.Arrange(_finalRect);
                double width = _finalRect.Width + X;
                if (width > maxWidth) maxWidth = width;

                _hSum += child.DesiredSize.Height + _ChildSpace;
                _index++;
            }

            return finalSize; // new Size(maxWidth, finalSize.Height);


        }

        protected override Size MeasureOverride(Size availableSize)
        {//V5            
            _TotalHeight = 0;
            _MaxWidth = 0;
            var parent = this.FindParent<NetworkTree>();

            if (!parent.IsExpanded)
                return new Size(0, 0);

            CheckLines(parent);
            foreach (FrameworkElement child in InternalChildren)
            {
                child.Measure(availableSize);
                _TotalHeight += child.DesiredSize.Height + _ChildSpace;
            }
            double _hSum = 0;
            _Rayon = _TotalHeight / 2 * 1.5;
            foreach (FrameworkElement child in InternalChildren)
            {
                double _h = (_TotalHeight / 2 - _hSum);
                double XFromCenter = Math.Sqrt(_Rayon * _Rayon - _h * _h);
                double X = XFromCenter - (_Rayon - _Rayon / _coef) + _Offset;
                double width = child.DesiredSize.Width + X;
                _hSum += child.DesiredSize.Height + _ChildSpace;
                
                if (width > _MaxWidth) _MaxWidth = width;
            }
            
            //if (availableSize.Width < _MaxWidth) _MaxWidth = availableSize.Width;
            //if (availableSize.Height < _TotalHeight) _TotalHeight = availableSize.Height;
            
            return new Size(_MaxWidth, _TotalHeight);
        }

        #endregion panel implementation

    }
}
